﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;

namespace SplendidCRM.Ext.Controllers
{
    public class AjaxController : Controller
    {
        public ActionResult Get(String view)
        {
            return View(view, new DynamicAjaxRequestParameters(k => Request.QueryString[k], k => Request.QueryString.GetValues(k) ?? new String[0]));
        }

        public ActionResult Post(String view)
        {
            return View(view, new DynamicAjaxRequestParameters(k => Request.Form[k], k => Request.Form.GetValues(k) ?? new String[0]));
        }

        public ActionResult Both(String view)
        {
            return View(view, new DynamicAjaxRequestParameters(k => Request[k], k => (Request.QueryString.GetValues(k) ?? new String[0]).Concat(Request.Form.GetValues(k) ?? new String[0]).ToArray()));
        }
    }

    class DynamicAjaxRequestParameters : DynamicObject
    {
        private readonly Func<String, String> _valueGetter;
        private readonly Func<String, String[]> _arrayGetter;

        public DynamicAjaxRequestParameters(Func<String, String> valueGetter, Func<String, String[]> arrayGetter)
        {
            _valueGetter = valueGetter;
            _arrayGetter = arrayGetter;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = GetMember(binder.Name);
            return true;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            result = GetMember(indexes[0]);
            return true;
        }

        private readonly IDictionary<String, Object> _cache = new Dictionary<String, Object>(StringComparer.OrdinalIgnoreCase);
        private Object GetMember(Object member)
        {
            var key = (member ?? String.Empty).ToString();
            Object result;
            if (!_cache.TryGetValue(key, out result))
            {
                if (key.EndsWith("[]"))
                {
                    result = _arrayGetter(key.Substring(0, key.Length - 2));
                }
                else
                {
                    result = _valueGetter(key);
                }
                _cache[key] = result;
            }
            return result;
        }
    }
}
